package ixRedis

import (
	"encoding/json"
	"strconv"
	"time"

	"github.com/garyburd/redigo/redis"
)

// BatchSet 批量设置键值
func (c *Client) BatchSet(kvs map[string]interface{}) error {
	if len(kvs) == 0 {
		return nil
	}

	conn, err := c.getConn()
	if err != nil {
		return err
	}
	defer conn.Close()

	// 使用管道批量设置
	conn.Send("MULTI")
	for key, value := range kvs {
		strValue := c.convertToString(value)
		fullKey := c.buildKey(key)
		conn.Send("SET", fullKey, strValue)
	}
	_, err = conn.Do("EXEC")
	return err
}

// BatchSetWithExpire 批量设置键值并指定过期时间
func (c *Client) BatchSetWithExpire(kvs map[string]interface{}, expiration time.Duration) error {
	if len(kvs) == 0 {
		return nil
	}

	conn, err := c.getConn()
	if err != nil {
		return err
	}
	defer conn.Close()

	// 使用管道批量设置
	conn.Send("MULTI")
	for key, value := range kvs {
		strValue := c.convertToString(value)
		fullKey := c.buildKey(key)
		if expiration > 0 {
			conn.Send("SET", fullKey, strValue, "EX", int(expiration.Seconds()))
		} else {
			conn.Send("SET", fullKey, strValue)
		}
	}
	_, err = conn.Do("EXEC")
	return err
}

// BatchGet 批量获取键值
func (c *Client) BatchGet(keys []string) (map[string]string, error) {
	if len(keys) == 0 {
		return make(map[string]string), nil
	}

	conn, err := c.getConn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	// 使用 MGET 批量获取
	args := make([]interface{}, len(keys))
	for i, key := range keys {
		args[i] = c.buildKey(key)
	}

	values, err := redis.Strings(conn.Do("MGET", args...))
	if err != nil {
		return nil, err
	}

	result := make(map[string]string)
	for i, key := range keys {
		if i < len(values) && values[i] != "" {
			result[key] = values[i]
		}
	}

	return result, nil
}

// BatchGetTyped 批量获取键值并解析到指定类型
func (c *Client) BatchGetTyped(keys []string, dest interface{}) error {
	// 这里可以根据需要实现批量获取并解析到结构体切片或map
	// 暂时返回未实现错误
	return redis.ErrNil
}

// convertToString 将值转换为字符串（内部方法）
func (c *Client) convertToString(value interface{}) string {
	// 复用 SetWithExpire 中的转换逻辑
	switch v := value.(type) {
	case string:
		return v
	case int:
		return strconv.FormatInt(int64(v), 10)
	case int8:
		return strconv.FormatInt(int64(v), 10)
	case int16:
		return strconv.FormatInt(int64(v), 10)
	case int32:
		return strconv.FormatInt(int64(v), 10)
	case int64:
		return strconv.FormatInt(v, 10)
	case uint:
		return strconv.FormatUint(uint64(v), 10)
	case uint8:
		return strconv.FormatUint(uint64(v), 10)
	case uint16:
		return strconv.FormatUint(uint64(v), 10)
	case uint32:
		return strconv.FormatUint(uint64(v), 10)
	case uint64:
		return strconv.FormatUint(v, 10)
	case float32:
		return strconv.FormatFloat(float64(v), 'f', -1, 32)
	case float64:
		return strconv.FormatFloat(v, 'f', -1, 64)
	case bool:
		return strconv.FormatBool(v)
	case []byte:
		return string(v)
	case nil:
		return ""
	default:
		// 对于复杂类型，使用JSON序列化
		jsonData, _ := json.Marshal(value)
		return string(jsonData)
	}
}
